package com.hyacinth.queue;

import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * 队列管理类
 * 用于创建队列
 * 采用{@link Future}实现线程安全
 * @author zhangfb
 * @version 1.0.0.1
 * @since JDK 1.8
 */
public class QueueManager {

    private static volatile QueueManager instance;

    private final ConcurrentHashMap<String, Future<Queue>> queueMap = new ConcurrentHashMap<String, Future<Queue>>(32);

    public static QueueManager getInstance() {
        if (instance == null) {
            synchronized (QueueManager.class) {
                if (instance == null) {
                    instance = new QueueManager();
                }
            }
        }
        return instance;
    }
    /**
     * 获取队列对象，如果为空，则创建
     * @param name 队列名称
     * @return 队列对象
     */
    public Queue getQueue(String name) {
        Future<Queue> value;
        try {
            value = queueMap.get(name);
            if (value == null) {
                value = putQueue(name);
            }
            return value.get();
        } catch (Exception ignore) {

        }
        return null;
    }

    /**
     * 创建队列对象
     * @param name 队列名称
     * @return 队列
     */
    private Future<Queue> putQueue(String name) {
        //把数据放到缓存
        Future<Queue> value;
        Callable<Queue> callable = new Callable<Queue>() {
            @Override
            public Queue call() throws Exception {
                return new Queue();
            }
        };
        FutureTask<Queue> futureTask = new FutureTask<Queue>(callable);
        // putIfAbsent方法如果不存在key对应的值，则将value以key加入Map，否则返回key对应的旧值。
        value = queueMap.putIfAbsent(name, futureTask);
        if (value == null) {
            value = futureTask;
            futureTask.run();
        }
        return value;
    }

}
